#include <stdio.h>  // 提供输入输出相关函数，例如scanf、printf
#include <stdlib.h> // 提供动态内存分配相关函数，例如malloc、free

// step 1# 定义方向数组，表示上下左右四个方向
int dir[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};  // 方向数组，用于在 BFS 中移动

typedef struct {
    int x;  // step 2# 表示坐标的 x 值
    int y;  // step 3# 表示坐标的 y 值
} Queue;

void bfs(int **grid, int **visited, int x, int y, int row, int col) {
    // step 4# 动态分配队列空间，用于 BFS 搜索
    Queue *queue = (Queue *)malloc(sizeof(Queue) * row * col); // 创建队列
    int front = 0;  // step 5# 队列的前端
    int rear = 0;   // step 6# 队列的后端
    queue[rear].x = x;  // step 7# 将起点坐标加入队列
    queue[rear].y = y;
    rear++;
    visited[x][y] = 1;  // step 8# 标记起点已访问

    // step 9# 循环进行 BFS 搜索，直到队列为空
    while(front < rear) {
        // step 10# 取出队列头节点并搜索其四个方向
        Queue head = queue[front++];  // 1# 取队列头部节点
        for(int i = 0; i < 4; i++) {
            int nextX = head.x + dir[i][0];  // step 11# 计算新坐标
            int nextY = head.y + dir[i][1];
            
            // step 12# 判断新坐标是否越界
            if (nextX < 0 || nextX >= row || nextY < 0 || nextY >= col) continue;

            // step 13# 判断该坐标是否未被访问且为目标值（1）
            if (visited[nextX][nextY] == 0 && grid[nextX][nextY] == 1) {
                // step 14# 将符合条件的新节点加入队列
                queue[rear].x = nextX;
                queue[rear].y = nextY;
                rear++;
                visited[nextX][nextY] = 1;  // step 15# 标记新节点已访问
            }
        }
    }
}

int main() {
    int row, col;
    // step 16# 输入行数和列数
    scanf("%d %d", &row, &col);

    // step 17# 动态分配二维数组 grid 和 visited
    int **grid = (int **)malloc(sizeof(int *) * row * col);  // step 18# 分配 grid 空间
    int **visited = (int **)malloc(sizeof(int *) * row * col);  // step 19# 分配 visited 空间

    // step 20# 初始化 grid 和 visited 数组
    for(int i = 0; i < row; i++) {
        grid[i] = (int *)malloc(sizeof(int) * col);  // step 21# 为每行分配空间
        visited[i] = (int *)malloc(sizeof(int) * col);  // step 22# 为每行分配空间
    }

    // step 23# 输入 grid 数据并初始化 visited 数组
    for(int i = 0; i < row; i++) {
        for(int j = 0; j < col; j++) {
            visited[i][j] = 0;  // step 24# 初始化 visited 数组为未访问
            scanf("%d", &grid[i][j]);  // step 25# 输入网格数据
        }
    }

    // step 26# 初始化岛屿计数器
    int count = 0;
    // step 27# 遍历 grid 数组，找出未访问的岛屿
    for(int i = 0; i < row; i++) {
        for(int j = 0; j < col; j++) {
            // step 28# 若该位置为 1 且未访问过，则进行 BFS 搜索
            if (visited[i][j] == 0 && grid[i][j] == 1) {
                count++;  // step 29# 增加岛屿数量
                bfs(grid, visited, i, j, row, col);  // step 30# 执行 BFS 搜索
            }
        }
    }

    // step 31# 输出岛屿数量
    printf("%d", count);  // step 32# 打印结果
    return 0;
}
